package iwhr.nsbd.util;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

public class Time {

    private LocalDateTime startTime;
    private LocalDateTime endTime;

    public Time(LocalDateTime startTime, LocalDateTime endTime) {
        this.startTime = startTime;
        this.endTime = endTime;
    }

    // 添加getter和setter方法
    public LocalDateTime getStartTime() {
        return startTime;
    }

    public void setStartTime(LocalDateTime startTime) {
        this.startTime = startTime;
    }

    public LocalDateTime getEndTime() {
        return endTime;
    }

    public void setEndTime(LocalDateTime endTime) {
        this.endTime = endTime;
    }


    public Time() {
    }

    /**时间调整方法*/


    private Map<Integer, List<TimeRange>> monthStartTimes ;
    private List<TimeRange> timeRanges ;


    public Time(Map<Integer, List<TimeRange>> monthStartTimes, List<TimeRange> timeRanges) {
        this.monthStartTimes = monthStartTimes;
        this.timeRanges = timeRanges;
    }


    //修正时间范围
    public ChangeDateRange getChangeDateRange(Map<Integer, List<TimeRange>> monthStartTimes, List<TimeRange> timeRanges, int nextMonth) {
        int localMonth = nextMonth - 1;
        if (localMonth == 0) {
            localMonth = 12;
        }
        List<TimeRange> dateRanges1 = monthStartTimes.get(localMonth);//本月时间段
        long totalHoursInMonth = 0;
        //本月范围中是否存在跨月时间段，如果有则新增下月时间段
        if (dateRanges1 != null) {
            for (TimeRange timeRange : dateRanges1) {
                LocalDateTime localStartTime = timeRange.getStartDateTime();//获取本月开始时间
                LocalDateTime localEndTime = timeRange.getEndDateTime();//获取本月结束时间
                boolean kyLocal = localStartTime.getMonthValue() != localEndTime.getMonthValue();//开始和结束时间中的月是否一致
                if (kyLocal) {//如果不一致
                    int daysOfMonth = 0;
                    GetDayOfMonth gd = new GetDayOfMonth();//获取当月天数构造器
                    daysOfMonth = gd.getDaysInMonth(localMonth);
                    LocalDateTime newStartTime = timeRange.getEndDateTime().withDayOfMonth(1).withHour(0);//设置结束时间为1号，并作为新的开始时间
                    LocalDateTime newEndTime = timeRange.getEndDateTime();//设置结束时间为10点，并作为新的结束时间
                    LocalDateTime newLocalEndTime = timeRange.getStartDateTime().withDayOfMonth(daysOfMonth).withHour(23).withMinute(59);//设置本月跨月时间为23：59：00
                    timeRange.setEndDateTime(newLocalEndTime);
                    //添加下月初时间段
                    timeRanges.add(new TimeRange(newStartTime, newEndTime));
                }
            }
        } else {
            System.out.println("上月运行时间范围为空");
        }
        //重新写入List
        for (TimeRange range : timeRanges) {
            LocalDateTime start = range.getStartDateTime();
            int month = start.getMonthValue();
            boolean hasSameData = false;
            // 检查是否存在相同时间
            for (TimeRange existingRange : monthStartTimes.getOrDefault(month, new ArrayList<>())) {
                if (existingRange.equals(range)) {
                    hasSameData = true;
                    break;
                }
            }
            if (hasSameData) {
                continue; // 如果已经存在相同时间段，跳出循环
            }
            if (!monthStartTimes.containsKey(month)) {
                monthStartTimes.put(month, new ArrayList<>());
            }
            monthStartTimes.get(month).add(range);
        }
        // 对每个月份的时间段列表进行排序
        for (List<TimeRange> ranges : monthStartTimes.values()) {
            ranges.sort(Comparator.comparing(TimeRange::getStartDateTime));
        }

        List<TimeRange> dateRanges = monthStartTimes.get(nextMonth);//下月时间段
        //下月范围中是否存在跨月时间段
        if (dateRanges != null) {
            for (int i = 0; i < dateRanges.size(); i++) {
                //计算出下月开始和结束时间
                LocalDateTime nextStartTime = dateRanges.get(i).getStartDateTime();//获取下月每个时间段的开始时间
                LocalDateTime nextEndTime = dateRanges.get(i).getEndDateTime();//获取下月每个时间段的结束时间
                boolean kyNext = nextStartTime.getMonthValue() != nextEndTime.getMonthValue();//看每个时间段的开始和结束时间是否跨到下下月
                if (kyNext) {
                    totalHoursInMonth += 1;
                    //如果跨月
                    //获取下月年份、月份
                    int yearInNext = nextStartTime.getYear();
                    int monthInNext = nextStartTime.getMonthValue();
                    // 获取下月天数
                    YearMonth yearMonth = YearMonth.of(yearInNext, monthInNext);
                    int daysInNextMonth = yearMonth.lengthOfMonth();
                    for (TimeRange range : dateRanges) {
                        LocalDateTime end = range.getEndDateTime();
                        if (end.getMonthValue() != monthInNext) {
                            // 修改结束时间的月份和日期
                            LocalDateTime updatedEnd = end.withYear(yearInNext).withMonth(monthInNext).withDayOfMonth(daysInNextMonth).withHour(23).withMinute(59);
                            // 更新TimeRange对象的结束时间
                            range.setEndDateTime(updatedEnd);
                        }
                    }
                }
                LocalDateTime nextStartTime1 = dateRanges.get(i).getStartDateTime();
                LocalDateTime nextEndTime2 = dateRanges.get(i).getEndDateTime();
                Duration d1 = Duration.between(nextStartTime1, nextEndTime2);
                totalHoursInMonth += d1.toHours();
            }
        } else {
            System.out.println("下月运行时间范围为空");
        }
        ChangeDateRange r = new ChangeDateRange();
        r.setDateRanges(dateRanges);
        r.setDateRanges1(dateRanges1);
        r.setTotalHoursInMonth(totalHoursInMonth);
        return r;
    }

    //记录修正后的时间范围，本月总小时


    //打印运行时间方法
    public static List<Time> pumpTimePrint(ChangeDateRange C, double[] dayToHours) {
        List<Time> results = new ArrayList<>();
        for (int i = 0; i < C.getDateRanges().size(); i++) {
            LocalDateTime nextStartTime = C.getDateRanges().get(i).getStartDateTime();
            LocalDateTime nextEndTime = C.getDateRanges().get(i).getEndDateTime();
            //判断每个时间段是否满足泵站运行时间（小时），不满足则修正为时间段时间。
            Duration d1 = Duration.between(nextStartTime, nextEndTime);
            long h = d1.toHours();
            if (nextEndTime.getMinute() == 59){//如果有跨月运行，小时数+1
                h += 1;
            }
            if (h <= dayToHours[i]) {
                double temp = dayToHours[i] - h;
                dayToHours[i + 1] += temp;
                dayToHours[i] = h;
            }
            double number = dayToHours[i];
            // 将浮点数转换为整数，然后取余数
            int integerPart = (int) number;
            double fractionalPart = number - integerPart;
            if (fractionalPart > 0.5){
                dayToHours[i] += 1;
            }
            Duration d2 = Duration.between(nextStartTime,nextStartTime.plusHours((long) dayToHours[i]));
            long h2 = d2.toHours();
            if (h2 != 0){
                LocalDateTime newEndTime = nextStartTime.plusHours((long) dayToHours[i]);
                if ((newEndTime.getMonthValue() == nextStartTime.getMonthValue() + 1) && newEndTime.getHour() == 0){//如果计算至24：00到下月1号，修正为上月月底的23:59分。
                    GetDayOfMonth day = new GetDayOfMonth();
                    Time result = new Time(nextStartTime, newEndTime.withMonth(nextStartTime.getMonthValue()).withDayOfMonth(day.getDaysInMonth(nextStartTime.getMonthValue())).withHour(23).withMinute(59));
                    results.add(result);
                }else {
                    Time result = new Time(nextStartTime, newEndTime);
                    results.add(result);
                }
            }

        }
        return results;
    }


    //获取当前月时间范围中，今天至月底的小时数方法
    public static double getLocalMonthHours(ChangeDateRange C, double localMonthHours , int nextMonth) {
        // 获取当前日期
        LocalDateTime currentDate1 = LocalDateTime.now();
        int a = currentDate1.getMonthValue() - nextMonth;
        int b =  currentDate1.getHour();

        if (a == -1) {
            for (int i = 0; i < C.getDateRanges().size(); i++) {
                // 获取当前日期
                LocalDateTime currentDate = LocalDateTime.now();

                LocalDateTime monthStartTime = C.getDateRanges().get(i).getStartDateTime();
                LocalDateTime monthEndTime = C.getDateRanges().get(i).getEndDateTime();
                boolean dataTime = currentDate.isAfter(monthStartTime) && currentDate.isBefore(monthEndTime);
                if (dataTime) {
                    if (b > 8){//如果计算时间超过8点，增加8点到此时的小时数。
                        LocalDateTime eightTime = currentDate1.withHour(8).withMinute(0).withSecond(0).withNano(0);
                        Duration d = Duration.between(eightTime, currentDate1);
                        localMonthHours += (double) d.toMinutes() /60;
                    }else if (b < 8 && (currentDate1.getDayOfMonth()!= monthStartTime.getDayOfMonth())){//如果早上8点前计算，增加昨天8点到现在的小时数
                        LocalDateTime eightTime = currentDate1.withHour(8).withMinute(0).withSecond(0).withNano(0).minusDays(1);
                        Duration d = Duration.between(eightTime, currentDate1);
                        localMonthHours += (double) d.toMinutes() /60;
                    }
                    Duration d = Duration.between(currentDate, monthEndTime);
                    localMonthHours += (double) d.toMinutes() /60;
                } else {
                    while (true) {
                        currentDate = currentDate.plusHours(1);
                        //终止循环条件，日期，小时数相等
                        int monthNum = currentDate.getDayOfMonth();
                        int monthHoursNum = currentDate.getHour();
                        int month = currentDate.getMonthValue();
                        boolean equalTime = (monthNum == monthStartTime.getDayOfMonth()) && (monthHoursNum == monthStartTime.getHour());
                        boolean equalMonthValue = (month == monthStartTime.getMonthValue());
                        if (equalTime) {
                            Duration d = Duration.between(currentDate, monthEndTime);
                            localMonthHours += (double) d.toMinutes() /60;//得出最终小时数
                            break;
                        }else if (!equalMonthValue){
                            break;

                        }
                    }
                }
            }
        }
        else {
            localMonthHours = 0;
        }
        return localMonthHours;
    }





    public Map<Integer, List<TimeRange>> getMonthStartTimes() {
        return monthStartTimes;
    }

    public void setMonthStartTimes(Map<Integer, List<TimeRange>> monthStartTimes) {
        this.monthStartTimes = monthStartTimes;
    }

    public List<TimeRange> getTimeRanges() {
        return timeRanges;
    }

    public void setTimeRanges(List<TimeRange> timeRanges) {
        this.timeRanges = timeRanges;
    }

}



